package org.custom.spring.boot.security.exceptions.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.custom.spring.boot.constant.Code;
import org.custom.spring.boot.constant.Message;
import org.custom.spring.boot.entity.Result;
import org.custom.spring.boot.security.exceptions.JwtException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 系统统一异常处理器
 *
 * @author LiKun
 * @date 2021/11/8 22:19
 */
@RestControllerAdvice
public class ExceptionHandlers {
    /**
     * JWT令牌解析出错
     *
     * @return Result<String> 提示信息
     */
    @ExceptionHandler(JwtException.class)
    public Result<String> jwtExceptionHandler() {
        return new Result<>(Code.TOKEN_ERROR, Message.TOKEN_ERROR);
    }

    /**
     * 处理 JSON 解析/生成问题
     *
     * @return 提示信息
     */
    @ExceptionHandler(JsonProcessingException.class)
    public Result<Object> jsonProcessingExceptionHandler() {
        return new Result<>(Code.FAIL, Message.FAIL);
    }

    /**
     * 处理账号密码错误异常
     *
     * @return 提示信息
     */
    @ExceptionHandler(BadCredentialsException.class)
    public Result<Object> badCredentialsExceptionHandler() {
        return new Result<>(Code.NAME_OR_PASS_ERROR, Message.NAME_OR_PASS_ERROR);
    }

    /**
     * 处理用户未登录/登陆失效异常
     *
     * @return 提示信息
     */
    @ExceptionHandler(InsufficientAuthenticationException.class)
    public Result<String> InsufficientAuthenticationExceptionHandler() {
        return new Result<>(Code.USER_NOT_LOGIN, Message.USER_NOT_LOGIN);
    }

    /**
     * 当用户账号不存在时将会抛出该异常
     *
     * @return Result<String> 提示信息
     */
    @ExceptionHandler(InternalAuthenticationServiceException.class)
    public Result<String> internalAuthenticationServiceExceptionHandler() {
        return new Result<>(Code.USER_NOT_EXITES, Message.USER_NOT_EXIST);
    }

    /**
     * 数据校验不符合规则
     *
     * @param exception 数据校验异常
     *
     * @return 相关提示信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) {
        return new Result<>(Code.REQUEST_PARAM_ERROR, exception.getBindingResult().getFieldError().getDefaultMessage());
    }
}
